﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Serialization;
using VersionComparer.Configuration;

namespace VersionComparer.DataModel
{
    /// <summary>
    /// This class represents a list of exclusion rules
    /// </summary>
    public class ExclusionRules : List<ExclusionRule >
    {
        #region constructors
        public ExclusionRules()
        {
        }
        public ExclusionRules(ItemNamePairList ownerList)
        {
            OwnerList = ownerList;
        }
        #endregion constructors

        #region properties
        [XmlIgnore]
        public ItemNamePairList OwnerList
        {
            get;
            set;
        }
        #endregion properties

        #region methods
        private void Save()
        {
            OwnerList.Save();
        }
        private bool RuleExists(ComparableItem item)
        {
            foreach (var rule in this)
            {
                if (rule.AppliesToNode(item))
                    return true;
            }
            return false;
        }
        private bool RemoveRuleFromItem(ComparableItem item, List<ComparableItem> rootItems)
        {
            for ( int i= Count - 1; i >= 0 ; i--)
            {
                var rule = this[i];
                if (rule.IsSubRuleOfItem(item))
                {
                    RemoveAt(i);
                    var root = item.Root;
                    if (!rootItems.Contains(root))
                        rootItems.Add(root);
                }
            }
            return false;
        }
        private bool AddRuleToNode(ComparableItem item, List<ComparableItem> fileItems)
        {
            if (!RuleExists(item))
            {
                this.Add(new ExclusionRule(item));
                var root = item.Root;
                if (!fileItems.Contains(root))
                    fileItems.Add(root);
                return true;
            }
            return false;
        }
        public List<ComparableItem> Toggle(ComparableItem[] items)
        {
            bool ruleExists = false;
            foreach (var item in items)
            {
                if (RuleExists(item) || RuleExists(item.RelatedItem))
                {
                    ruleExists = true;
                    break;
                }
            }
            if (ruleExists)
                return Remove(items);
            else
                return Add(items);
        }
        public List<ComparableItem> Remove(ComparableItem[] items)
        {
            List<ComparableItem> rootItems = new List<ComparableItem>();
            foreach (var item in items)
            {
                ComparableItem item1 = item;
                ComparableItem item2 = item1.RelatedItem;
                RemoveRuleFromItem(item1, rootItems);
                RemoveRuleFromItem(item2, rootItems);
            }
            foreach (var rootItem in rootItems)
                rootItem.ResetRules();
            Save();
            return rootItems;
        }
        public List<ComparableItem> Add(ComparableItem[] nodes)
        {
            List<ComparableItem> fileNodes = new List<ComparableItem>();
            foreach (var node in nodes)
            {
                ComparableItem node1 = node;
                ComparableItem node2 = node1.RelatedItem;
                AddRuleToNode(node1, fileNodes);
                AddRuleToNode(node2, fileNodes);
            }
            foreach (var fileNode in fileNodes)
                fileNode.ResetRules();
            Save();
            return fileNodes;
        }
        public bool HasRuleApplied (ComparableItem item)
        {

            foreach (var rule in this)
            {
                if (rule.WasCreatedOverNode (item))
                    return true;
            }
            return false;
        }
        #endregion methods

    }
}
